package com.seed.uaa.util;

import cn.dev33.satoken.SaManager;
import cn.dev33.satoken.config.SaTokenConfig;
import cn.dev33.satoken.fun.SaFunction;
import cn.dev33.satoken.listener.SaTokenEventCenter;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.util.StrUtil;
import com.seed.application.A;
import com.seed.application.env.AppEnv;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class StpKit {
    public static StpLogic type;
    public static final Map<String, StpLogic> types = new ConcurrentHashMap<>();

    private StpKit() {
    }

    public static String getLoginType() {
        return getStpLogic().getLoginType();
    }

    public static void setStpLogic(StpLogic newStpLogic) {
        String loginType = newStpLogic.getLoginType();
        types.put(loginType, newStpLogic);
        newStpLogic.setConfig(new SaTokenConfig().setTokenName("satoken." + loginType));
        SaManager.putStpLogic(newStpLogic);
        SaTokenEventCenter.doSetStpLogic(newStpLogic);
    }

    public static StpLogic getStpLogic() {
        String key = AppEnv.getAppKey();
        if(StrUtil.isBlank(key)) {
            if(type == null) type = new StpLogic("~");
            return type;
        }

        StpLogic stpLogic = types.get(key);
        if(stpLogic == null) setStpLogic(new StpLogic(key));

        return types.get(key);
    }

    public static String getTokenName() {
        return getStpLogic().getTokenName();
    }

    public static void setTokenValue(String tokenValue) {
        getStpLogic().setTokenValue(tokenValue);
    }

    public static void setTokenValue(String tokenValue, int cookieTimeout) {
        getStpLogic().setTokenValue(tokenValue, cookieTimeout);
    }

    public static void setTokenValue(String tokenValue, SaLoginModel loginModel) {
        getStpLogic().setTokenValue(tokenValue, loginModel);
    }

    public static String getTokenValue() {
        return getStpLogic().getTokenValue();
    }

    public static String getTokenValueNotCut() {
        return getStpLogic().getTokenValueNotCut();
    }

    public static SaTokenInfo getTokenInfo() {
        return getStpLogic().getTokenInfo();
    }

    public static void login(Object id) {
        getStpLogic().login(id);
    }

    public static void login(Object id, String device) {
        getStpLogic().login(id, device);
    }

    public static void login(Object id, boolean isLastingCookie) {
        getStpLogic().login(id, isLastingCookie);
    }

    public static void login(Object id, long timeout) {
        getStpLogic().login(id, timeout);
    }

    public static void login(Object id, SaLoginParameter loginParameter) {
        getStpLogic().login(id, loginParameter);
    }

    public static String createLoginSession(Object id) {
        return getStpLogic().createLoginSession(id);
    }

    public static String createLoginSession(Object id, SaLoginParameter loginParameter) {
        return getStpLogic().createLoginSession(id, loginParameter);
    }

    public static void logout() {
        getStpLogic().logout();
    }

    public static void logout(Object loginId) {
        getStpLogic().logout(loginId);
    }

    public static void logout(Object loginId, String device) {
        getStpLogic().logout(loginId, device);
    }

    public static void logoutByTokenValue(String tokenValue) {
        getStpLogic().logoutByTokenValue(tokenValue);
    }

    public static void kickout(Object loginId) {
        getStpLogic().kickout(loginId);
    }

    public static void kickout(Object loginId, String device) {
        getStpLogic().kickout(loginId, device);
    }

    public static void kickoutByTokenValue(String tokenValue) {
        getStpLogic().kickoutByTokenValue(tokenValue);
    }

    public static void replaced(Object loginId, String device) {
        getStpLogic().replaced(loginId, device);
    }

    public static boolean isLogin() {
        return getStpLogic().isLogin();
    }

    public static boolean isLogin(Object loginId) {
        return getStpLogic().isLogin(loginId);
    }

    public static void checkLogin() {
        getStpLogic().checkLogin();
    }

    public static Object getLoginId() {
        return getStpLogic().getLoginId();
    }

    public static <T> T getLoginId(T defaultValue) {
        return getStpLogic().getLoginId(defaultValue);
    }

    public static Object getLoginIdDefaultNull() {
        return getStpLogic().getLoginIdDefaultNull();
    }

    public static String getLoginIdAsString() {
        return getStpLogic().getLoginIdAsString();
    }

    public static int getLoginIdAsInt() {
        return getStpLogic().getLoginIdAsInt();
    }

    public static long getLoginIdAsLong() {
        return getStpLogic().getLoginIdAsLong();
    }

    public static Object getLoginIdByToken(String tokenValue) {
        return getStpLogic().getLoginIdByToken(tokenValue);
    }

    public static Object getExtra(String key) {
        return getStpLogic().getExtra(key);
    }

    public static Object getExtra(String tokenValue, String key) {
        return getStpLogic().getExtra(tokenValue, key);
    }

    public static SaSession getSessionByLoginId(Object loginId, boolean isCreate) {
        return getStpLogic().getSessionByLoginId(loginId, isCreate);
    }

    public static SaSession getSessionBySessionId(String sessionId) {
        return getStpLogic().getSessionBySessionId(sessionId);
    }

    public static SaSession getSessionByLoginId(Object loginId) {
        return getStpLogic().getSessionByLoginId(loginId);
    }

    public static SaSession getSession(boolean isCreate) {
        return getStpLogic().getSession(isCreate);
    }

    public static SaSession getSession() {
        return getStpLogic().getSession();
    }

    public static SaSession getTokenSessionByToken(String tokenValue) {
        return getStpLogic().getTokenSessionByToken(tokenValue);
    }

    public static SaSession getTokenSession() {
        return getStpLogic().getTokenSession();
    }

    public static SaSession getAnonTokenSession() {
        return getStpLogic().getAnonTokenSession();
    }

    public static void updateLastActiveToNow() {
        getStpLogic().updateLastActiveToNow();
    }

    public static void checkActiveTimeout() {
        getStpLogic().checkActiveTimeout();
    }

    public static long getTokenTimeout() {
        return getStpLogic().getTokenTimeout();
    }

    public static long getTokenTimeout(String token) {
        return getStpLogic().getTokenTimeout(token);
    }

    public static long getSessionTimeout() {
        return getStpLogic().getSessionTimeout();
    }

    public static long getTokenSessionTimeout() {
        return getStpLogic().getTokenSessionTimeout();
    }

    public static long getTokenActiveTimeout() {
        return getStpLogic().getTokenActiveTimeout();
    }

    public static void renewTimeout(long timeout) {
        getStpLogic().renewTimeout(timeout);
    }

    public static void renewTimeout(String tokenValue, long timeout) {
        getStpLogic().renewTimeout(tokenValue, timeout);
    }

    public static List<String> getRoleList() {
        return getStpLogic().getRoleList();
    }

    public static List<String> getRoleList(Object loginId) {
        return getStpLogic().getRoleList(loginId);
    }

    public static boolean hasRole(String role) {
        return getStpLogic().hasRole(role);
    }

    public static boolean hasRole(Object loginId, String role) {
        return getStpLogic().hasRole(loginId, role);
    }

    public static boolean hasRoleAnd(String... roleArray) {
        return getStpLogic().hasRoleAnd(roleArray);
    }

    public static boolean hasRoleOr(String... roleArray) {
        return getStpLogic().hasRoleOr(roleArray);
    }

    public static void checkRole(String role) {
        getStpLogic().checkRole(role);
    }

    public static void checkRoleAnd(String... roleArray) {
        getStpLogic().checkRoleAnd(roleArray);
    }

    public static void checkRoleOr(String... roleArray) {
        getStpLogic().checkRoleOr(roleArray);
    }

    public static List<String> getPermissionList() {
        return getStpLogic().getPermissionList();
    }

    public static List<String> getPermissionList(Object loginId) {
        return getStpLogic().getPermissionList(loginId);
    }

    public static boolean hasPermission(String permission) {
        return getStpLogic().hasPermission(permission);
    }

    public static boolean hasPermission(Object loginId, String permission) {
        return getStpLogic().hasPermission(loginId, permission);
    }

    public static boolean hasPermissionAnd(String... permissionArray) {
        return getStpLogic().hasPermissionAnd(permissionArray);
    }

    public static boolean hasPermissionOr(String... permissionArray) {
        return getStpLogic().hasPermissionOr(permissionArray);
    }

    public static void checkPermission(String permission) {
        getStpLogic().checkPermission(permission);
    }

    public static void checkPermissionAnd(String... permissionArray) {
        getStpLogic().checkPermissionAnd(permissionArray);
    }

    public static void checkPermissionOr(String... permissionArray) {
        getStpLogic().checkPermissionOr(permissionArray);
    }

    public static String getTokenValueByLoginId(Object loginId) {
        return getStpLogic().getTokenValueByLoginId(loginId);
    }

    public static String getTokenValueByLoginId(Object loginId, String device) {
        return getStpLogic().getTokenValueByLoginId(loginId, device);
    }

    public static List<String> getTokenValueListByLoginId(Object loginId) {
        return getStpLogic().getTokenValueListByLoginId(loginId);
    }

    public static List<String> getTokenValueListByLoginId(Object loginId, String device) {
        return getStpLogic().getTokenValueListByLoginId(loginId, device);
    }

//    public static List<TokenSign> getTokenSignListByLoginId(Object loginId, String device) {
//        return getStpLogic().getTokenSignListByLoginId(loginId, device);
//    }

    public static String getLoginDevice() {
        return getStpLogic().getLoginDevice();
    }

    public static String getLoginDeviceTypeByToken(String tokenValue) {
        return getStpLogic().getLoginDeviceTypeByToken(tokenValue);
    }

    public static long getTokenLastActiveTime() {
        return getStpLogic().getTokenLastActiveTime();
    }

    public static List<String> searchTokenValue(String keyword, int start, int size, boolean sortType) {
        return getStpLogic().searchTokenValue(keyword, start, size, sortType);
    }

    public static List<String> searchSessionId(String keyword, int start, int size, boolean sortType) {
        return getStpLogic().searchSessionId(keyword, start, size, sortType);
    }

    public static List<String> searchTokenSessionId(String keyword, int start, int size, boolean sortType) {
        return getStpLogic().searchTokenSessionId(keyword, start, size, sortType);
    }

    public static void disable(Object loginId, long time) {
        getStpLogic().disable(loginId, time);
    }

    public static boolean isDisable(Object loginId) {
        return getStpLogic().isDisable(loginId);
    }

    public static void checkDisable(Object loginId) {
        getStpLogic().checkDisable(loginId);
    }

    public static long getDisableTime(Object loginId) {
        return getStpLogic().getDisableTime(loginId);
    }

    public static void untieDisable(Object loginId) {
        getStpLogic().untieDisable(loginId);
    }

    public static void disable(Object loginId, String service, long time) {
        getStpLogic().disable(loginId, service, time);
    }

    public static boolean isDisable(Object loginId, String service) {
        return getStpLogic().isDisable(loginId, service);
    }

    public static void checkDisable(Object loginId, String... services) {
        getStpLogic().checkDisable(loginId, services);
    }

    public static long getDisableTime(Object loginId, String service) {
        return getStpLogic().getDisableTime(loginId, service);
    }

    public static void untieDisable(Object loginId, String... services) {
        getStpLogic().untieDisable(loginId, services);
    }

    public static void disableLevel(Object loginId, int level, long time) {
        getStpLogic().disableLevel(loginId, level, time);
    }

    public static void disableLevel(Object loginId, String service, int level, long time) {
        getStpLogic().disableLevel(loginId, service, level, time);
    }

    public static boolean isDisableLevel(Object loginId, int level) {
        return getStpLogic().isDisableLevel(loginId, level);
    }

    public static boolean isDisableLevel(Object loginId, String service, int level) {
        return getStpLogic().isDisableLevel(loginId, service, level);
    }

    public static void checkDisableLevel(Object loginId, int level) {
        getStpLogic().checkDisableLevel(loginId, level);
    }

    public static void checkDisableLevel(Object loginId, String service, int level) {
        getStpLogic().checkDisableLevel(loginId, service, level);
    }

    public static int getDisableLevel(Object loginId) {
        return getStpLogic().getDisableLevel(loginId);
    }

    public static int getDisableLevel(Object loginId, String service) {
        return getStpLogic().getDisableLevel(loginId, service);
    }

    public static void switchTo(Object loginId) {
        getStpLogic().switchTo(loginId);
    }

    public static void endSwitch() {
        getStpLogic().endSwitch();
    }

    public static boolean isSwitch() {
        return getStpLogic().isSwitch();
    }

    public static void switchTo(Object loginId, SaFunction function) {
        getStpLogic().switchTo(loginId, function);
    }

    public static void openSafe(long safeTime) {
        getStpLogic().openSafe(safeTime);
    }

    public static void openSafe(String service, long safeTime) {
        getStpLogic().openSafe(service, safeTime);
    }

    public static boolean isSafe() {
        return getStpLogic().isSafe();
    }

    public static boolean isSafe(String service) {
        return getStpLogic().isSafe(service);
    }

    public static boolean isSafe(String tokenValue, String service) {
        return getStpLogic().isSafe(tokenValue, service);
    }

    public static void checkSafe() {
        getStpLogic().checkSafe();
    }

    public static void checkSafe(String service) {
        getStpLogic().checkSafe(service);
    }

    public static long getSafeTime() {
        return getStpLogic().getSafeTime();
    }

    public static long getSafeTime(String service) {
        return getStpLogic().getSafeTime(service);
    }

    public static void closeSafe() {
        getStpLogic().closeSafe();
    }

    public static void closeSafe(String service) {
        getStpLogic().closeSafe(service);
    }
}
